<?php

namespace App\Exceptions;

use Illuminate\Auth\Access\AuthorizationException;
use Illuminate\Database\Eloquent\ModelNotFoundException;
use Illuminate\Validation\ValidationException;
use Laravel\Lumen\Exceptions\Handler as ExceptionHandler;
use Symfony\Component\HttpKernel\Exception\HttpException;
use Throwable;
use App\Common\Enum\{TrueCode};
use App\Common\Http\Basics\Error;
use App\Common\Helper;
use App\Common\Http\Result;
// use App\Common\Message\Basics\Error as ErrorMessage;
use App\Dao\Logs\ErrorDao;

use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Symfony\Component\HttpKernel\Exception\MethodNotAllowedHttpException;

class Handler extends ExceptionHandler
{
    /**
     * A list of the exception types that should not be reported.
     *
     * @var array
     */
    protected $dontReport = [
        AuthorizationException::class,
        HttpException::class,
        ModelNotFoundException::class,
        ValidationException::class,
    ];

    /**
     * Report or log an exception.
     *
     * This is a great spot to send exceptions to Sentry, Bugsnag, etc.
     *
     * @param  \Throwable  $exception
     * @return void
     *
     * @throws \Exception
     */
    public function report(Throwable $exception)
    {
        // parent::report($exception);
    }


    /**
     * Render an exception into an HTTP response.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Throwable  $exception
     * @return \Illuminate\Http\Response|\Illuminate\Http\JsonResponse
     *
     * @throws \Throwable
     */
    public function render($request, Throwable $e)
    {

        //如果lumen 404内部错误先返回
        if ($e instanceof NotFoundHttpException)  return Helper::toHttpJson(new Result([], Error::API_NOT_FIND));
        //请求方式错误
        else if ($e instanceof MethodNotAllowedHttpException) return  Helper::toHttpJson(new Result([], Error::API_METHOD_ERROR, [] ,['method' => $request->method()]));
        //100错误
        else if ($e instanceof HttpCustomException && $e->getResult()->getTrueCodeName() === TrueCode::SUCCESS->name)  return Helper::toHttpJson($e->getResult());

        else {

            $error = $e instanceof HttpCustomException && $e->getException() ?
            [

                'line' => $e->getException()->getLine(),

                'file' => $e->getException()->getFile(),

                'error' => $e->getMessage() . ' error:message   '. $e->getException()->getMessage(),

            ]
            :  [

                'line' => $e->getLine(),

                'file' => $e->getFile(),

                'error' => $e->getMessage(),

            ];

            $merge = ['enum' => $e instanceof HttpCustomException ? [
                'class' =>  $e->getResult()->getHttpEnum()::class,
                'name' => $e->getResult()->getHttpName(),
                'trueCodeName' => $e->getResult()->getTrueCodeName(),
                'code' => $e->getResult()->getHttpVal(),
            ]  : null];

            // //写入日志

                $logPostion = ErrorDao::asyncAdd(array_merge($error, $merge), $request);  //加入mongodb日志



            // //请求方式错误

            if (config('app.debug') === true) {     //测试环境输出错误信息

                 $error = array_merge( $error , $logPostion);

                 $result = $e instanceof HttpCustomException ? new Result($error,  $e->getResult()->getHttpEnum()  , [] ,  $e->getResult()->getReplace() ) : new Result($error, Error::SERVER_ERROR);

            } else {

                 $result = new Result($logPostion, Error::SERVER_ERROR);
            }


            return Helper::toHttpJson($result);

        }
    }
}
